@stacks/wallet-sdk
@stacks/wallet-sdk
is a library for building wallets for the Stacks blockchain.
Features
- Generate a wallet from scratch
- Encrypt a wallet with a password
- Restore a wallet and associated accounts
- Generate new accounts in a wallet
- Sign transactions for the Stacks blockchain
- Register usernames on BNS, the naming service built into the Stacks Blockchain
Key Concepts
Secret Key
A Secret Key is a 12 or 24 word mnemonic phrase, which can be used to deterministically generate a wallet and any number of addresses. When the same Secret Key is used, the exact same addresses will be generated. The Secret Key acts as an easily rememberable and highly secure mechanism for backing up a wallet.
Secret Keys conform to the BIP 39 standard.
Wallet
A "wallet" is a set of private keys for an individual user. A wallet will contain any number of accounts.
Account
Accounts act as a way for users to separate assets and data within their own account. You could think of accounts like different Google accounts while logged into Gmail. You can easily switch between different accounts, but they all have different data and information.
- Each account is associated with an individual Stacks address.
- Each account has its own balance and state on the blockchain.
- Accounts can have usernames.
- When a user logs in through a wallet, they choose an individual account from their wallet.
- Application data is completely segregated from different accounts.
- External parties have no way of knowing that two accounts belong to the same wallet
Derivation paths
Private keys are generated according to the BIP32 and BIP44 standards.
The "coin type" for the Stacks blockchain is 5757
.
The private key for each account's STX address is derived from m/44'/5757'/0'/0/n
, where n
is the index of the account.
Usage
Installation
With NPM:
npm install @stacks/wallet-sdk
Generate a Secret Key
By default, a random 24-word Secret Key is generated, using 256 bits of entropy. You can generate a random 12-word key by passing 128
as the entropy
argument.
import { generateSecretKey } from '@stacks/wallet-sdk';
const secretKey = generateSecretKey();
const secretKey128 = generateSecretKey(128);
Generate a wallet
Create a random Secret Key and a Wallet
object. When a wallet is generated, the first account is automatically generated as well.
import { generateWallet, generateSecretKey } from '@stacks/wallet-sdk';
const password = 'password';
const secretKey = generateSecretKey();
const wallet = await generateWallet({
secretKey,
password,
});
A Wallet
is a normal JavaScript object with the following properties:
interface Wallet {
salt: string;
rootKey: string;
configPrivateKey: string;
encryptedSecretKey: string;
accounts: Account[];
}
Generating new accounts
Accounts allow users to use separate Stacks addresses from within the same wallet. Each account has it's own Stacks address and balance. When a user logs into an app, they choose a specific account.
When using generateNewAccount
, the new account is created with next index, based on the existing accounts in a wallet. For example, if a wallet has 5 accounts, calling generateNewAccount
will make the sixth account. The generateNewAccount
treats as the input wallet as immutable. It returns a new wallet object with all available accounts (based on the input wallet object and the additional generated account).
import { generateWallet, generateNewAccount } from '@stacks/wallet-sdk';
let wallet = await generateWallet({
secretKey,
password,
});
wallet = generateNewAccount(wallet);
An Account
is a JavaScript object with these properties:
interface Account {
stxPrivateKey: string;
dataPrivateKey: string;
salt: string;
username?: string;
profile?: Profile;
appsKey: string;
index: number;
}
Restoring accounts for an existing Wallet
When a user restores their wallet in a new app, you can automatically restore any previously-used accounts from the same wallet. It will also restore any usernames owned by this user.
The private keys used to encrypt this data is derived from the path m/44/5757'/0'/1
. This data is stored in Gaia, the decentralized storage system in the Stacks network. Users can host their own Gaia hub, and this library's API can use that Gaia hub, if provided.
import { restoreWalletAccounts } from '@stacks/wallet-sdk';
const restoredWallet = await restoreWalletAccounts({
wallet: baseWallet,
gaiaHubUrl: 'https://hub.blockstack.org',
network: new StacksMainnet(),
});
Making an authentication response
With an account, you can generate an authentication response, which conforms to the Stacks authentication protocol. The resulting authResponse
is a string, representing a signed JSON web token. Learn more about the authentication protocol.
const transitPublicKey = 'xxxx';
const authResponse = await makeAuthResponse({
gaiaHubUrl: 'https://hub.blockstack.org',
appDomain: 'https://example-app.com',
transitPublicKey,
scopes: ['publish_data'],
account,
});
Usage with @stacks/transactions
This library is meant to be used in conjunction with the @stacks/transactions
library for signing transactions.
Getting an account's STX address
import { getStxAddress } from '@stacks/wallet-sdk';
import { TransactionVersion } from '@stacks/transactions';
const account = wallet.accounts[0];
const testnetAddress = getStxAddress({ account, transactionVersion: TransactionVersion.Testnet });
const mainnetAddress = getStxAddress({ account, transactionVersion: TransactionVersion.Mainnet });
Signing Stacks Transactions
You can generate signed transactions by following the documentation from @stacks/transactions
. Use the stxPrivateKey
of an account as the senderKey
option when creating a transaction.
import { StacksMainnet } from '@stacks/network';
import { makeSTXTokenTransfer } from '@stacks/transactions';
const network = new StacksMainnet();
const account = wallet.accounts[0];
const txOptions = {
recipient: 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159',
amount: 12345n,
senderKey: account.stxPrivateKey,
network,
};
const transaction = await makeSTXTokenTransfer(txOptions);